package com.desay.pangoo.itmt.repository.spec;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
 * @Description： 通用表达式
 * 
 * @author shouyi.huang@desay-svautomotive.com on 2019年7月23日下午8:35:34
 * @Modified By： [] on [] for [修改说明]
 *
 */
public class SimpleExpression implements ExpandCriterion {
	private static final String POINT = ".";
	/** 属性名 */
	private String fieldName;
	/** 对应值 */
	private Object value;
	/** 计算符 */
	private Operator operator;

	protected SimpleExpression(String fieldName, Object value, Operator operator) {
		this.fieldName = fieldName;
		this.value = value;
		this.operator = operator;
	}

	public String getFieldName() {
		return fieldName;
	}

	public Object getValue() {
		return value;
	}

	public Operator getOperator() {
		return operator;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
		Path expression = null;
		if (fieldName.contains(POINT)) {
			String[] names = fieldName.split("\\.");
			expression = root.get(names[0]);
			for (int i = 1; i < names.length; i++) {
				try {
					expression = expression.get(names[i]);
				} catch (Exception e) {
					// 多表左连接:1对多的情况
					Join join = root.join(names[i - 1]);
					expression = join.get(names[i]);
				}
			}
		} else {
			expression = root.get(fieldName);
		}

		switch (operator) {
		case EQ:
			return builder.equal(expression, value);
		case NE:
			return builder.notEqual(expression, value);
		case LIKE:
			return builder.like(expression, "%" + value + "%");
		case LT:
			return builder.lessThan(expression, (Comparable) value);
		case GT:
			return builder.greaterThan(expression, (Comparable) value);
		case LTE:
			return builder.lessThanOrEqualTo(expression, (Comparable) value);
		case GTE:
			return builder.greaterThanOrEqualTo(expression, (Comparable) value);
		case ISNULL:
			return builder.isNull(expression);
		case ISNOTNULL:
			return builder.isNotNull(expression);
		case ISMEMBER:
			return builder.isMember(value, expression);
		case ISNOTEMPTY:
			return builder.isNotEmpty(expression);
		case ISEMPTY:
			return builder.isEmpty(expression);
		case GROUPBY:
			query.groupBy(expression);
			return null;
		default:
			return null;
		}
	}
}
